// Copyright 2011 Google Inc. All Rights Reserved.
// Author: Hans Larsen

// Define our own namespace.
(function() {
  var real_xhr = window.XMLHttpRequest;
  var cache = {};

  function defineClassGetters(obj) {
    for(var i = 1, ii = arguments.length; i < ii; ++i) {
      // Need some closure.
      (function(name) {
        obj.__defineGetter__(name, function() {
          return real_xhr[name];
        });
      })(arguments[i]);
    }
  }
  function defineInstanceSetters(obj) {
    for(var i = 1, ii = arguments.length; i < ii; ++i) {
      // Need some closure.
      (function(name) {
        obj.__defineGetter__(name, function() { return this._xhr[name]; });
        obj.__defineSetter__(name, function(v) { this._xhr[name] = v; });
      })(arguments[i]);
    }
  }

  var xhr = function() {
    this._xhr = new real_xhr();
  };

  defineClassGetters(xhr.prototype, "UNSENT", "OPENED", "HEADERS_RECEIVED", "LOADING", "DONE");
  defineInstanceSetters(xhr.prototype, "onreadystatechange", "readyState", "status",
      "responseText", "responseHtml");

  // The open method sets internal state to be able to backoff in send().
  xhr.prototype.open = function(method, url, async, user, password) {
    this._async = async;
    this._method = method;
    return this._xhr.open(method, url, async, user, password);
  }
  // The send() method does all the magic.
  xhr.prototype.send = function() {
    this._xhr.send();
  }

  for(var key in real_xhr.prototype) {
    if (!(key in xhr.prototype)) {
      if (typeof real_xhr.prototype[key] === "function") {
        (function(key) {
          // Simply encapsulate each methods so that we call the right method
          // from the underlying object.
          xhr.prototype[key] = function() {
            var args = Array.prototype.slice.call(arguments);
            return this._xhr[key].apply(this._xhr, args);
          }
        })(key);
      }
    }
  };

  // Replace the default XHR.
  if (window['overrideXMLHttpRequest'] !== undefined &&
      window['overrideXMLHttpRequest'] === true) {
    window['XMLHttpRequest'] = xhr;
  }
  // In any case, we set this class to be used by others.
  window['BackoffXMLHttpRequest'] = xhr;
  // And this one if we override the default, could be useful.
  xhr['OldXMLHttpRequest'] = real_xhr;
})();
